<?php
////////////////////////////////////////////////////////////////////////////
//                                                                        //
// NOTICE OF COPYRIGHT                                                    //
//                                                                        //
// Dean`s Office for Moodle                                               //
// Электронный деканат                                                    //
// <http://deansoffice.ru/>                                               //
//                                                                        //
// Copyright (C) 2008-2999  Alex Djachenko (Алексей Дьяченко)             //
// alex-pub@my-site.ru                                                    //
// Copyright (C) 2008-2999  Evgenij Cigancov (Евгений Цыганцов)           //
// Copyright (C) 2008-2999  Ilia Smirnov (Илья Смирнов)                   // 
// Copyright (C) 2008-2999  Mariya Rojayskaya (Мария Рожайская)           // 
//                                                                        //
// This program is free software: you can redistribute it and/or modify   //
// it under the terms of the GNU General Public License as published by   //
// the Free Software Foundation, either version 3 of the Licensen.        //
//                                                                        //
// This program is distributed in the hope that it will be useful,        //
// but WITHOUT ANY WARRANTY; without even the implied warranty of         //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          //
// GNU General Public License for more details.                           //
//                                                                        //
// You should have received a copy of the GNU General Public License      //
// along with this program.  If not, see <http://www.gnu.org/licenses/>.  //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

/** Класс стандартных функций интерфейса
 * 
 */
class dof_im_acl implements dof_plugin_im
{
    /**
     * @var dof_control
     */
    protected $dof;
    // **********************************************
    // Методы, предусмотренные интерфейсом plugin
    // **********************************************
    /** Метод, реализующий инсталяцию плагина в систему
     * Создает или модифицирует существующие таблицы в БД
     * и заполняет их начальными значениями
     * @return boolean
     * Может надо возвращать массив с названиями таблиц и результатами их создания?
     * чтобы потом можно было распечатать сообщения о результатах обновления
     * @access public
     */
    public function install()
    {
        return true;
    }
    /** Метод, реализующий обновление плагина в системе
     * Создает или модифицирует существующие таблицы в БД
     * @param string $old_version - версия установленного в системе плагина
     * @return boolean
     * Может надо возвращать массив с названиями таблиц и результатами их создания/изменения?
     * чтобы потом можно было распечатать сообщения о результатах обновления
     * @access public
     */
    public function upgrade($oldversion)
    {
        return true; 
    }
    /** Возвращает версию установленного плагина
     * @return string
     * @access public
     */
    public function version()
    {
        return 2012052900;
    }
    /** Возвращает версии интерфейса Деканата, 
     * с которыми этот плагин может работать
     * @return string
     * @access public
     */
    public function compat_dof()
    {
        return 'aquarium';
    }

    /** Возвращает версии стандарта плагина этого типа, 
     * которым этот плагин соответствует
     * @return string
     * @access public
     */
    public function compat()
    {
        return 'angelfish';
    }
    
    /** Возвращает тип плагина
     * @return string 
     * @access public
     */
    public function type()
    {
        return 'im';
    }
    /** Возвращает короткое имя плагина
     * Оно должно быть уникально среди плагинов этого типа
     * @return string
     * @access public
     */
    public function code()
    {
        return 'acl';
    }
    /** Возвращает список плагинов, 
     * без которых этот плагин работать не может
     * @return array
     * @access public
     */
    public function need_plugins()
    {
        return array('modlib'=>array('nvg'=>2008060300),
                     'storage'=>array('acl'=>2011041800,
                                      'aclwarrantagents'=>2011040500,
                                      'aclwarrants'=>2011040501) );
    }
    /** Список обрабатываемых плагином событий 
     * @return array - array(array('plugintype'=>..,'plugincode'=>..,'eventcode'=>..),...)
     * @access public
     */
    public function list_catch_events()
    {
       return array();
    }
    /** Требуется ли запуск cron в плагине
     * @return bool
     * @access public
     */
    public function is_cron()
    {
       return false;
    }
    /** Проверяет полномочия на совершение действий
     * @param string $do - идентификатор действия, которое должно быть совершено
     * @param int $id_obj - идентификатор экземпляра объекта, 
     * по отношению к которому это действие должно быть применено
     * @param int $userid - идентификатор пользователя в Moodle, полномочия которого проверяются
     * @return bool true - можно выполнить указанное действие по отношению к выбранному объекту
     * false - доступ запрещен
     * @access public
     */
    public function is_access($do, $objid = NULL, $userid = NULL)
    {
        if ( $this->dof->is_access('admin') )
        {// манагеру можно все
            return true;
        }

        return false;

    }    
	/** Требует наличия полномочия на совершение действий
     * @param string $do - идентификатор действия, которое должно быть совершено
     * @param int $id_obj - идентификатор экземпляра объекта, 
     * по отношению к которому это действие должно быть применено
     * @param int $user_id - идентификатор пользователя, полномочия которого проверяются
     * @return bool true - можно выполнить указанное действие по отношению к выбранному объекту
     * false - доступ запрещен
     * @access public
     */
    public function require_access($do, $objid = NULL, $userid = NULL)
    {
        // Используем функционал из $DOFFICE
        //return $this->dof->require_access($do, NULL, $userid);
        if ( ! $this->is_access($do, $objid, $userid) )
        {
            $notice = "acl/{$do} (block/dof/im/acl: {$do})";
            if ($objid){$notice.=" id={$objid}";}
            $this->dof->print_error('nopermissions','',$notice);
        }
    }
    /** Обработать событие
     * @param string $gentype - тип модуля, сгенерировавшего событие
     * @param string $gencode - код модуля, сгенерировавшего событие
     * @param string $eventcode - код задания
     * @param int $intvar - дополнительный параметр 
     * @param mixed $mixedvar - дополнительные параметры
     * @return bool - true в случае выполнения без ошибок
     * @access public
     */
    public function catch_event($gentype,$gencode,$eventcode,$intvar,$mixedvar)
    {
        return true;
    }
    /** Запустить обработку периодических процессов
     * @param int $loan - нагрузка (1 - только срочные, 2 - нормальный режим, 3 - ресурсоемкие операции)
     * @param int $messages - количество отображаемых сообщений (0 - не выводить,1 - статистика,
     *  2 - индикатор, 3 - детальная диагностика)
     * @return bool - true в случае выполнения без ошибок
     * @access public
     */
    public function cron($loan,$messages)
    {
        return true;
    }
    /** Обработать задание, отложенное ранее в связи с его длительностью
     * @param string $code - код задания
     * @param int $intvar - дополнительный параметр 
     * @param mixed $mixedvar - дополнительные параметры
     * @return bool - true в случае выполнения без ошибок
     * @access public
     */
    public function todo($code,$intvar,$mixedvar)
    {
        return true;
    }
    /** Конструктор
     * @param dof_control $dof - идентификатор действия, которое должно быть совершено
     * @access public
     */
    public function __construct($dof)
    {
        $this->dof = $dof;
    }
    // **********************************************
    // Методы, предусмотренные интерфейсом im
    // **********************************************
    /** Возвращает текст для отображения в блоке на странице dof
     * @param string $name - название набора текстов для отображания
     * @param int $id - id текста в наборе
     * @return string - html-код содержимого блока
     */
    function get_block($name, $id = 1)
    {
        $rez = '';
  
        return $rez;
    }
    /** Возвращает html-код, который отображается внутри секции
     * @param string $name - название набора текстов для отображания
     * @param int $id - id текста в наборе
     * @return string  - html-код содержимого секции секции
     */
    function get_section($name, $id = 1)
    {
        $rez = '';
        switch ($name)
        {

        }
        return $rez;
    }
     /** Возвращает текст, отображаемый в блоке на странице курса MOODLE 
      * @return string  - html-код для отображения
      */
    public function get_blocknotes()
    {
        return "<a href='{$this->dof->url_im($this->code(),'/index.php')}'>"
                    .$this->dof->get_string('page_main_name')."</a>";
    }

    // **********************************************
    //              Собственные методы
    // **********************************************
    
    /** Получить URL к собственным файлам плагина
     * @param string $adds[optional] - фрагмент пути внутри папки плагина
     *                                 начинается с /. Например '/index.php'
     * @param array $vars[optional] - параметры, передаваемые вместе с url
     * @return string - путь к папке с плагином 
     * @access public
     */
    public function url($adds='', $vars=array())
    {
        return $this->dof->url_im($this->code(), $adds, $vars);
    }
    
    /** Получить заголовок для списка таблицы, или список полей
     * для списка отображения одного объекта 
     * @return array
     */
    private function get_fields_description($type)
    {
        switch ( $type )
		{
			case 'person':
            return array($this->dof->get_string('plugintype', 'acl'),
                         $this->dof->get_string('plugincode', 'acl'),
                         $this->dof->get_string('code', 'acl'),
                         $this->dof->get_string('legend', 'acl'),
                         $this->dof->get_string('objectid', 'acl'),
                         $this->dof->get_string('department', 'acl')); 
            case 'warrant':
            return array($this->dof->get_string('plugintype', 'acl'),
                         $this->dof->get_string('plugincode', 'acl'),
                         $this->dof->get_string('code', 'acl'),
                         $this->dof->get_string('legend', 'acl'),
                         $this->dof->get_string('objectid', 'acl'),
                         $this->dof->modlib('ig')->igs('actions'));
            case 'acl':
            return array($this->dof->modlib('ig')->igs('fio'),
                         $this->dof->modlib('ig')->igs('actions')); 
		}
    }

   /** Возвращает html-код таблицы
     * @param array $date - данные в таблицу
     * @return string - html-код или пустая строка
     */
    private function print_table($date,$type)
    {
        // рисуем таблицу
        $table = new object();
        $table->tablealign = "center";
        $table->width = "100%";
        $table->cellpadding = 2;
        $table->cellspacing = 2;
        $table->size = array ('90px','130px','150px','200px','70px','100px');
        $table->align = array ("center","center","center","center","center","center");
        // шапка таблицы
        $table->head =  $this->get_fields_description($type);
        // заносим данные в таблицу     
        $table->data = $date;
        return $this->dof->modlib('widgets')->print_table($table,true);
    }
    
    /**
     * Возвращает html-код отображения 
     * информации о нескольких группах
     * @param массив $list - массив записей 
     * периодов, которые надо отобразить 
     * @return mixed string в string html-код или false в случае ошибки
     */
    public function get_table_right_person($list)
    {
        if ( ! is_array($list))
        {// переданны данные неверного формата
        	return false;
        }
        $data = array();
    	// заносим данные в таблицу
    	foreach ($list as $obj)
    	{   
    	    $department = $this->dof->storage('departments')->get_field($obj->departmentid,'name').' <br>['.
    	                  $this->dof->storage('departments')->get_field($obj->departmentid,'code').']';
    	    $data[] = array($obj->plugintype,$obj->plugincode,$obj->code,
    	                    $this->dof->get_string($obj->plugintype.'_'.$obj->plugincode.'_'.$obj->code,'acl','<br>'),
    	                    $obj->objectid,$department);
    	}
    	
    	// выводим таблицу на экран
        return $this->print_table($data,'person');
    }
    
    /**
     * Возвращает html-код отображения 
     * информации о нескольких группах
     * @param массив $list - массив записей 
     * периодов, которые надо отобразить 
     * @return mixed string в string html-код или false в случае ошибки
     */
    public function get_table_right_warrant($list)
    {
        $addvars = array();
        $addvars['departmentid'] = optional_param('departmentid', 0, PARAM_INT);
        if ( ! is_array($list))
        {// переданны данные неверного формата
        	return false;
        }
        $data = array();
    	// заносим данные в таблицу
    	foreach ($list as $obj)
    	{   
    	    $actions = '<a href='.$this->dof->url_im('acl','/aclpersons.php?id='.
            $obj->id,$addvars).'><img src="'.$this->dof->url_im('acl', '/icons/persons_acl.png').'" 
                alt="'.$this->dof->get_string('view_acl_person', 'acl').'" 
                title="'.$this->dof->get_string('view_acl_person', 'acl').'"></a>';
            $actions .= '<a href='.$this->dof->url_im('acl','/delete.php?id='.
            $obj->id,$addvars).'><img src="'.$this->dof->url_im('acl', '/icons/delete.png').'" 
                alt="'.$this->dof->get_string('delete_acl', 'acl').'" 
                title="'.$this->dof->get_string('delete_acl', 'acl').'"></a>';
    	    $data[] = array($obj->plugintype,$obj->plugincode,$obj->code,
    	                    $this->dof->get_string($obj->plugintype.'_'.$obj->plugincode.'_'.$obj->code,'acl','<br>'),
    	                    $obj->objectid,$actions);
    	}
    	
    	// выводим таблицу на экран
        return $this->print_table($data,'warrant');
    }
    
    /**
     * Возвращает html-код отображения 
     * информации о нескольких группах
     * @param массив $list - массив записей 
     * периодов, которые надо отобразить 
     * @return mixed string в string html-код или false в случае ошибки
     */
    public function get_table_persons_acl($list)
    {
        $addvars = array();
        $addvars['departmentid'] = optional_param('departmentid', 0, PARAM_INT);
        if ( ! is_array($list))
        {// переданны данные неверного формата
        	return false;
        }
        $data = array();
    	// заносим данные в таблицу
    	foreach ($list as $obj)
    	{   
    	    $personname = '<a href='.$this->dof->url_im('persons','/view.php?id='.
            $obj->id,$addvars).'>'.$this->dof->storage('persons')->get_fullname($obj->id).'</a>';
    	    //покажем ссылку на страницу просмотра
            $actions = '<a href='.$this->dof->url_im('acl','/personacl.php?id='.
            $obj->id,$addvars).'><img src="'.$this->dof->url_im('acl', '/icons/list_acl.png').'" 
                alt="'.$this->dof->get_string('view_acl_person', 'acl').'" 
                title="'.$this->dof->get_string('view_acl_person', 'acl').'"></a>';
    	    $data[] = array($personname,$actions);
    	}
    	
    	// выводим таблицу на экран
        return $this->print_table($data,'acl');
    }
    
    /**
     * Сохранение доверенных лиц для переданных пользователей
     * @param object $warrantagent - объект с данными для таблицы warrantagents
     * @param object $persolist - массив с id персон
     * @return bool
     */
    public function apply_to_insert_warrantagents($aclwarrantid, $departmentid, $begindate, 
    		$enddate, $noextend, $personlist) 
    {
        if ( ! empty($personlist))
        {
           foreach ($personlist as $personid)
           {   
               if ( ! $this->add_warrantagent($aclwarrantid, $departmentid, $begindate, 
               		$enddate, $noextend, $personid))
               {
                   return false;
               }
           }
           
           return true;
        }
        
        return false;
    }
    
    /**
     * Сохранение доверенного лица
     * @param object $warrantagent - объект с данными для таблицы warrantagents
     * @return bool
     */
    public function add_warrantagent($aclwarrantid, $departmentid, $begindate,
            $enddate, $noextend, $personid) 
    {
    	$rez = true;
    	
        $record = new object();
        $record->baseptype = 'storage';
        $record->basepcode = 'persons';
        $record->basetype = 'record';
        $record->aclwarrantid = $aclwarrantid;
        $record->departmentid = $departmentid;
        $record->begindate	  = $begindate;
        $record->datecreate	  = time();
        $record->duration 	  = $enddate - $begindate;
        $record->noextend	  = $noextend;
        $record->personid	  = $personid;
		$record->baseid		  = $personid;
		$record->basepcode	  = 'persons';
		
        if (! $pid = $this->dof->storage('aclwarrantagents')->add($record))
        {
        	return false;
        }
        
        // получаем статусы пользователя и доверенности
        $perstat = $this->dof->storage('persons')->get_field(array('id' => $personid), 'status');
        $warstat = $this->dof->storage('aclwarrants')->get_field(array('id' => $aclwarrantid), 'status');
        
        // добавляем ту же запись, но с измененными basepcode и baseid
        $record->basepcode = 'departments';
        $record->baseid = $record->departmentid;
        
        if ( ! $did = $this->dof->storage('aclwarrantagents')->add($record))
        {
            return false;
        }
        
        // если персона и доверенность активны - активируем доверенное лицо
        if ($perstat == 'normal' AND $warstat == 'active')
        {
            $rez = $rez && $this->dof->workflow('aclwarrantagents')->change($did,'active');
            $rez = $rez && $this->dof->workflow('aclwarrantagents')->change($pid,'active');
        }
        
    	return $rez;
    }
    
    /**
     * Обновление субдоверенности для переданных пользователей
     * @param object $warrantagent - объект с данными для таблицы warrantagents
     * @param object $persolist - массив с id персон
     * @return bool
     */
    
    public function apply_to_update_warrantagents($data, $personlist) {
        
        $res = true;
        
        if ( ! empty($personlist))
        {
            // массив доверенных лиц, использующих данную доверенность 
            if ( ! $warrantagents = $this->dof->storage('aclwarrantagents')->get_records(
                    array('aclwarrantid' => $data->aclwarrantid, 'status' => 'active')))
            {
                return false;
            }
            
            foreach ($personlist as $personid)
            {
                $match = false;
               
                foreach ($warrantagents as $key => $warrantagent)
                {
                    if ($warrantagent->personid == $personid)
                    {// обновляем дынные доверенного лица
                        
                        $obj = new object();
                        $obj->id = $warrantagent->id;
                        $obj->begindate = $data->begindate;
                        $obj->duration = $data->duration;
                        $obj->noextend = $data->noextend;
                        
                        $res = $this->update_warrantagent($obj) AND $res;
                       
                        unset($warrantagents[$key]);
                        $match = true;
                    }   
                }
                
                // не найдено - значит новый warrantagent
                if (!$match)
                {
                    $data->personid = $personid;
                    $data->baseid = $personid;
                    
                    $res = $this->add_warrantagent($data) AND $res;
                }
            }
            
            // все необновленные записи в warrantagents отправляем в архив
            if (!empty($warrantagents))
            {
                foreach ($warrantagents as $warrantagent)
                {
                    $obj = new object();
                    $obj->id = $warrantagent->id;
                    $obj->status = 'archive';
                    $res = $this->dof->storage('aclwarrantagents')->update($obj) AND $res;
                }
            }
             
            return $res;
        }
    
        return false;
    }
    
    /**
     * Обновление доверенного лица
     * @param object $warrantagent - объект с данными для таблицы warrantagents
     * @return bool
     */
    public function update_warrantagent($obj)
    {
        // основные проверки
        if (!is_object($obj) OR empty($obj->id) OR !is_int_string($obj->id))
        {
            return false;
        }
        
        if ( ! $this->dof->storage('aclwarrantagents')->update($obj))
        {
            return false;
        }
        
        return true;
    }
    
    

   
    
}